<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  
  <title>Jenkins + Gitea实现持续集成 | 阿栋的博客 | 翻身不粘锅</title>

  
  <meta name="author" content="A栋">
  

  
  <meta name="description" content="随笔随记，遇到什么记录什么，主要撰写学习大前端路上遇到的难题和心得。共勉">
  

  
  <meta name="keywords" content="blog">
  

  <meta id="viewport" name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui">
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black">

  <meta property="og:title" content="Jenkins + Gitea实现持续集成"/>

  <meta property="og:site_name" content="阿栋的博客"/>

  
  <meta property="og:image" content="/blog/favicon.ico"/>
  

  <link href="/blog/favicon.ico" rel="icon">
  <link rel="alternate" href="/blog/atom.xml" title="阿栋的博客" type="application/atom+xml">
  <link rel="stylesheet" href="/blog/css/style.css" media="screen" type="text/css">
<meta name="generator" content="Hexo 4.2.1"></head>


<body>
<div class="blog">
  <div class="content">

    <header>
  <div class="site-branding">
    <h1 class="site-title">
      <a href="/blog/">阿栋的博客</a>
    </h1>
    <p class="site-description">翻身不粘锅</p>
  </div>
  <nav class="site-navigation">
    <ul>
      
        <li><a href="/blog/">主页</a></li>
      
        <li><a href="/blog/archives">归档</a></li>
      
    </ul>
  </nav>
</header>

    <main class="site-main posts-loop">
    <article>

  
    
    <h3 class="article-title"><span>Jenkins + Gitea实现持续集成</span></h3>
    
  

  <div class="article-top-meta">
    <span class="posted-on" style="margin-left: 0;">
      <a href="/blog/jenkins/jenkins-gitea-continuous-integration/" rel="bookmark">
        <time class="entry-date published" datetime="2020-07-27T21:46:02.000Z">
          2020-07-28
        </time>
      </a>
    </span>
    
      <!-- 不蒜子统计 -->
      <span id="busuanzi_container_page_pv" style='display:none'>
        <i class="icon-smile icon"></i> 阅读数：<span id="busuanzi_value_page_pv"></span>次
      </span>
    
  </div>


  

  <div class="article-content">
    <div class="entry">
      
        <p><em>本文默认你已安装 <a href="https://www.jenkins.io/zh/doc/book/installing/" target="_blank" rel="noopener">jenkins</a>和 <a href="https://docs.gitea.io/en-us/install-with-docker/" target="_blank" rel="noopener">gitea</a></em></p>
<p>持续集成是指开发代码的实践，当上传代码之后，立即进行单元测试，与原代码相比判断是否可以集成到一起。每次集成通过自动构建的校验，发现构建中的错误</p>
<p>下面将介绍在Docker容器内，使用Jenkins和Gitea完成代码自动化打包、发布和部署的两种方案</p>
<a id="more"></a>
<h1 id="方案一、不安装Gitea插件，自建webhook"><a href="#方案一、不安装Gitea插件，自建webhook" class="headerlink" title="方案一、不安装Gitea插件，自建webhook"></a>方案一、不安装Gitea插件，自建webhook</h1><h3 id="创建项目"><a href="#创建项目" class="headerlink" title="创建项目"></a>创建项目</h3><p>在gitea上创建项目，填写项目名称其他一律默认</p>
<p><img src="/images/image-20200728144604955.png" alt="image-20200728144604955"></p>
<p>在Jenkins上创建项目，类型选择自由风格的项目（项目名最好一致方便辨认），其他配置先不管，点保存</p>
<p><img src="/images/image-20200728144858415.png" alt="image-20200728144858415"></p>
<h3 id="分配密钥"><a href="#分配密钥" class="headerlink" title="分配密钥"></a>分配密钥</h3><p>在本地生成公私钥对</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh-keygen -t rsa -b 4096 -C "your_email"</span><br></pre></td></tr></table></figure>

<p>在Jenkins的<strong>全局凭证</strong>里添加私钥，选择SSH，输入名称和创建时设的密码</p>
<p><img src="/images/image-20200728150944078.png" alt="image-20200728150944078"></p>
<p>在gitea项目的<strong>仓库设置</strong> -&gt; <strong>管理部署密钥</strong>，添加.pub结尾的公钥</p>
<p><img src="/images/image-20200728152106056.png" alt="image-20200728152106056"></p>
<h3 id="配置jenkins项目"><a href="#配置jenkins项目" class="headerlink" title="配置jenkins项目"></a>配置jenkins项目</h3><p>进入之前新建的jenkins项目配置页面，<strong>源码管理</strong>选择<strong>Git</strong>，填入gitea项目的SSH链接，凭证选刚才添加的</p>
<p><img src="/images/image-20200728153933816.png" alt="image-20200728153933816"></p>
<p>配置<strong>构建触发器</strong>，勾选<strong>触发远程构建</strong>，在身份验证令牌（也就是Token）输入一串自定义字符串</p>
<p><img src="/images/image-20200728154321374.png" alt="image-20200728154321374"></p>
<h3 id="创建webhook"><a href="#创建webhook" class="headerlink" title="创建webhook"></a>创建webhook</h3><p>进入gitea项目的<strong>仓库设置</strong> -&gt; <strong>管理web钩子</strong>，添加Gitea类型</p>
<p><img src="/images/image-20200728154723498.png" alt="image-20200728154723498"></p>
<p>目标URL模式如下：Jenkins访问地址/job/Jenkins项目名/build?token=Jenkins项目中配置的身份验证令牌，其他默认</p>
<p><img src="/images/image-20200728155307582.png" alt="image-20200728155307582"></p>
<h3 id="测试推送"><a href="#测试推送" class="headerlink" title="测试推送"></a>测试推送</h3><p>进入刚才新建的web钩子，测试推送</p>
<p><img src="/images/image-20200728160011918.png" alt="image-20200728160011918"></p>
<blockquote>
<p>不过这里有个问题，这个链接在不同的服务器上使用是没有问题的，但是如果<strong>gitea和Jenkins运行在同一台服务器上会请求失败报403错误</strong>：HTTP ERROR 403 No valid crumb was included in the request</p>
<p><img src="/images/image-20200728161128096.png" alt="image-20200728161128096"></p>
<p>这是因为Jenkins的跨域问题。不过自2.204.6版本开始，Jenkins就删除了禁用跨站请求伪造保护的功能，现在需要添加凭证到请求中才可访问</p>
</blockquote>
<p>进入jenkins<strong>个人设置</strong> -&gt; <strong>API Token</strong>，生成新token并复制</p>
<p><img src="/images/image-20200728160314948.png" alt="image-20200728160314948"></p>
<p>重新配置web钩子，新模式如下：jenkinsID(登录名):token@Jenkins访问地址/job/Jenkins项目名/build?token=Jenkins项目中配置的身份验证令牌</p>
<p><img src="/images/image-20200728160729339.png" alt="image-20200728160729339"></p>
<p>测试推送，成功</p>
<p><img src="/images/image-20200728161415907.png" alt="image-20200728161415907"></p>
<h1 id="方案二、使用Gitea插件，自动生成webhook（推荐）"><a href="#方案二、使用Gitea插件，自动生成webhook（推荐）" class="headerlink" title="方案二、使用Gitea插件，自动生成webhook（推荐）"></a>方案二、使用Gitea插件，自动生成webhook（推荐）</h1><h3 id="安装插件"><a href="#安装插件" class="headerlink" title="安装插件"></a>安装插件</h3><p>进入<strong>系统管理</strong> -&gt; <strong>插件管理</strong>，安装gitea插件并重启</p>
<p><img src="/images/image-20200728170237434.png" alt="image-20200728170237434"></p>
<h3 id="配置Gitea服务"><a href="#配置Gitea服务" class="headerlink" title="配置Gitea服务"></a>配置Gitea服务</h3><p>进入<strong>系统管理</strong> -&gt; <strong>系统配置</strong> -&gt; <strong>Gitea Server</strong>，新增gitea服务。设置名称和gitea的访问地址，勾选Manage hooks让gitea服务自动帮你在项目新增web钩子</p>
<p><img src="/images/image-20200728172742247.png" alt="image-20200728172742247"></p>
<p>添加凭证推荐用gitea管理员的token， 在gitea的<strong>个人设置</strong> -&gt; <strong>应用</strong>里生成令牌（token），凭证添加范围选择系统</p>
<p><img src="/images/image-20200728172439864.png" alt="image-20200728172439864"></p>
<p><img src="/images/image-20200728172634946.png" alt="image-20200728172634946"></p>
<h3 id="创建组织和生成“jenkins”token"><a href="#创建组织和生成“jenkins”token" class="headerlink" title="创建组织和生成“jenkins”token"></a>创建组织和生成“jenkins”token</h3><p>使用管理员账户登录gitea，创建组织</p>
<p><img src="/images/image-20200728175452658.png" alt="image-20200728175452658"></p>
<p>进入<strong>管理后台</strong> -&gt; <strong>账户管理</strong>，创建用户名为“jenkins”的账户（该号专门用于生成token）并添加到刚才创建的组织中</p>
<p><img src="/images/image-20200728180217199.png" alt="image-20200728180217199"></p>
<p><img src="/images/image-20200728180244077.png" alt="image-20200728180244077"></p>
<p>退出gitea，用“Jenkins”账号登录，进入<strong>个人设置</strong> -&gt; <strong>应用</strong>，生成token并复制</p>
<p><img src="/images/image-20200728180548791.png" alt="image-20200728180548791"></p>
<h3 id="新建jenkins任务"><a href="#新建jenkins任务" class="headerlink" title="新建jenkins任务"></a>新建jenkins任务</h3><p>新建任务，类型选择Gitea Organization</p>
<p><img src="/images/image-20200728181014043.png" alt="image-20200728181014043"></p>
<p>配置<strong>Projects</strong> -&gt; <strong>Gitea Organization</strong>，添加凭证，范围选该项目，使用刚才“jenkins”账户生成的token。Owner组织名称需要和gitea的组织名一致，保存</p>
<p><img src="/images/image-20200728181351366.png" alt="image-20200728181351366"></p>
<p>因为还未在组织创建仓库，所以扫描出来的存储库为0</p>
<p><img src="/images/image-20200728181753105.png" alt="image-20200728181753105"></p>
<h3 id="创建gitea项目"><a href="#创建gitea项目" class="headerlink" title="创建gitea项目"></a>创建gitea项目</h3><p>拥有者选刚才创建的组织，其他默认</p>
<p><img src="/images/image-20200728181945175.png" alt="image-20200728181945175"></p>
<p>用SSH拉取该项目，在根目录创建名为Jenkinsfile的脚本文件，添加脚本示例：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Jenkinsfile</span></span><br><span class="line">pipeline &#123;</span><br><span class="line">    agent any</span><br><span class="line"></span><br><span class="line">    stages &#123;</span><br><span class="line">        stage(<span class="string">'Build'</span>) &#123;</span><br><span class="line">            steps &#123;</span><br><span class="line">                echo <span class="string">'hello world'</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>Gitea Organization就是靠Jenkinsfile文件来识别项目。推送完毕后，在Jenkins的组织文件夹（刚才新建的任务）内会生成同名项目，在gitea的项目设置里，也会自动生成webhook</p>
<p><img src="/images/image-20200728183247985.png" alt="image-20200728183247985"></p>
<p><img src="/images/image-20200728183238041.png" alt="image-20200728183238041"></p>
<h3 id="测试推送-1"><a href="#测试推送-1" class="headerlink" title="测试推送"></a>测试推送</h3><p>成功</p>
<p><img src="/images/image-20200728183538380.png" alt="image-20200728183538380"></p>
<p><img src="/images/image-20200728183541485.png" alt="image-20200728183541485"></p>
<p><em>Jenkinsfile是脚本文件，和 Linux的 shell文件类似，具体操作看<a href="https://class.imooc.com/lesson/1165#mid=28189" target="_blank" rel="noopener">第七周的最后四节</a>或<a href="https://www.jenkins.io/zh/doc/book/pipeline/jenkinsfile/" target="_blank" rel="noopener">官方文档</a></em></p>
<blockquote>
<h3 id="参考网站"><a href="#参考网站" class="headerlink" title="参考网站"></a>参考网站</h3><p><a href="https://stackoverflow.com/questions/38137760/jenkins-rest-api-create-job" target="_blank" rel="noopener">https://stackoverflow.com/questions/38137760/jenkins-rest-api-create-job</a></p>
<p><a href="https://blog.csdn.net/erhaiou2008/article/details/103983755" target="_blank" rel="noopener">https://blog.csdn.net/erhaiou2008/article/details/103983755</a></p>
<p><a href="https://www.cnblogs.com/kazihuo/p/12937071.html" target="_blank" rel="noopener">https://www.cnblogs.com/kazihuo/p/12937071.html</a></p>
<p><a href="http://willless.com/jenkins-and-gitea-automated-packaging.html" target="_blank" rel="noopener">http://willless.com/jenkins-and-gitea-automated-packaging.html</a></p>
<p><a href="https://plugins.jenkins.io/gitea/" target="_blank" rel="noopener">https://plugins.jenkins.io/gitea/</a></p>
</blockquote>

      
    </div>

  </div>

  <div class="article-footer">
    <div class="article-meta pull-left">

    
      

    <span class="post-categories">
      <i class="icon-categories"></i>
        <a href="/blog/categories/自动化/">自动化</a>, <a href="/blog/categories/jenkins/">jenkins</a>
    </span>
    

    
    

    <span class="post-tags">
      <i class="icon-tags"></i>
        <a href="/blog/tags/jenkins/">jenkins</a><a href="/blog/tags/gitea/">gitea</a><a href="/blog/tags/持续集成/">持续集成</a><a href="/blog/tags/webhook/">webhook</a>
    </span>
    

    </div>

    
  </div>
</article>

  
	<section id="comment" class="comment">
		<div id="gitalk-container"></div>
	</section>
	<link rel="stylesheet" href="https://unpkg.com/gitalk/dist/gitalk.css">
	<script src="https://unpkg.com/gitalk/dist/gitalk.min.js"></script>
	<script>
		var gitalk = new Gitalk({
			clientID: '1571fb8dcfe72a03e4ad',
			clientSecret: '7c96e2aab4e22aec865b7821e409b8b876f5e35b',
			repo: 'NicholasKoji.github.io',
			owner: 'NicholasKoji',
			admin: ['NicholasKoji'],
			id: location.pathname,
			distractionFreeMode: false
		})

		gitalk.render('gitalk-container')
	</script>







    </main>

    <footer class="site-footer">
  <p class="site-info">
    Proudly powered by <a href="https://hexo.io/" target="_blank">Hexo</a> and
    Theme by <a href="https://github.com/CodeDaraW/Hacker" target="_blank">Hacker</a>
    </br>
    
    &copy; 2020 A栋
    
  </p>
  
    <!-- 不蒜子统计 -->
    <span id="busuanzi_container_site_pv">
      本站总访问量<span id="busuanzi_value_site_pv"></span>次
    </span>
    <span class="post-meta-divider">|</span>
    <span id="busuanzi_container_site_uv" style='display:none'>
      本站访客数<span id="busuanzi_value_site_uv"></span>人
    </span>
    <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
  
</footer>
    
  </div>
</div>
</body>
</html>